package com.xw.qxypt.modules.socket;


import com.xw.qxypt.modules.entity.DataCollection;
import com.xw.qxypt.modules.entity.LhpEquipmentEntity;
import com.xw.qxypt.modules.service.LhpInstallationPointService;
import com.xw.qxypt.modules.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;

@Service
public class CollectorSocketServer {

    private static final int PORT = 4001;// 监听的端口号

    @Autowired
    private LhpInstallationPointService lhpInstallationPointService;

    public void init() {
        //初始化设备连接列表
        lhpInstallationPointService.refreshDataCollectionMap(HspUtil.map);
        try {
            System.out.println("开启socket端口"+PORT);
            ServerSocket serverSocket = new ServerSocket(PORT);
            while (true) {
                // 一旦有堵塞, 则表示服务器与客户端获得了连接
                Socket client = serverSocket.accept();
                //client.setTcpNoDelay(true);
                // 处理这次连接
                String ip = client.getInetAddress().getHostAddress();
                new HandlerThread(client);
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("服务器异常: " + e.getMessage());
        }
    }
    //采集定时任务
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void poll(){
        System.out.println("----------------------poll");
        for (Map.Entry<String,DataCollection> entry : HspUtil.map.entrySet()) {
            DataCollection dc = entry.getValue();
            Socket socket = dc.getSocket();
            if(socket!=null && !socket.isClosed()) {
                new pollThread(dc);
            }
        }
    }
    //定时刷新设备连接，确保添加新设备生效
    @Scheduled(cron = "0 0/1 * * * *")
    public void refreshDataCollectionList(){
        System.out.println("-----------refreshDataCollectionList-----------");
        lhpInstallationPointService.refreshDataCollectionMap(HspUtil.map);
    }
    //定时将数据存入数据库
    @Scheduled(cron = "0 0/5 * * * *")
    public void insert(){
        System.out.println("-----------insert-----------");
        try {
            lhpInstallationPointService.insertCollectionData(HspUtil.map);
        } catch (Exception e) {

            e.printStackTrace();
        }
    }

    public void delay(){
        try {
            Thread.sleep(20000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送二进制报文
     * @param mbapADUMeter
     */
    public String sendData(String mbapADUMeter, OutputStream out) {
        String mes = null;
        byte[] buffer = new byte[mbapADUMeter.length() / 2];
        String contentHex = mbapADUMeter;
        for (int i = 0; i < contentHex.length(); i += 2) {
            try {
                buffer[i / 2] = (byte) (0xff & Integer.parseInt(contentHex
                        .substring(i, i + 2), 16));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        try {
            out.write(buffer);
            out.flush();
        } catch (IOException e) {
            mes = "sendFalse";
        }
        return mes;
    }
    /***************************数据报文接收开始******************************/
    private class HandlerThread implements Runnable {

        private String sensorNo;
        private Socket socket;
        private Date collectDate = new Date();
        private final int BUFSIZE = 1024 * 8;// 初始接收数据的总字节数
        byte[] receiveBuf = new byte[BUFSIZE];// 接收数据的缓冲区

        public HandlerThread(Socket client) {
            socket = client;
            new Thread(this).start();
        }

        public void run() {
            String ip = socket.getInetAddress().getHostAddress();
            if(HspUtil.map.containsKey(ip)){//维萨拉走着
                Socket clientSocket = HspUtil.map.get(ip).getSocket();
                    if(clientSocket == null || clientSocket.isClosed()){
                        //存放会话
                        HspUtil.map.get(ip).setSocket(socket);
                        System.out.println("建立连接"+ip);
                    }
                InputStream is = null;
                try {
                    is = socket.getInputStream();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                String info = null;
                StringBuffer sb = new StringBuffer();
                List<String> infolist = new ArrayList<>();
                try {
                    Map<String, LhpEquipmentEntity> equipmentMap=HspUtil.map.get(ip).getEquipmentMap();
                    List<LhpEquipmentEntity> leeList =  new ArrayList<LhpEquipmentEntity>(equipmentMap.values());
                    if(leeList.size()>0){
                        LhpEquipmentEntity lem = leeList.get(0);
                        if(lem.getManufactorType()==0 && lem.getEquipmentType()==0) {
                            while (!((info = br.readLine()) == null)) {
                                sb.append(info);
                                if ("=".equals(info)) {
                                    MessageTranslatorUtil.saveVaisalaDate(sb.toString(), HspUtil.map, ip);
                                    sb = new StringBuffer();
                                }
                            }
                        }else if(lem.getManufactorType()==0 && lem.getEquipmentType()==1) {
                            while (!((info = br.readLine()) == null)) {
                                for (int i = 0; i < info.split(" ").length; i++) {
                                    if (!"".equals(info.split(" ")[i])) {
                                        infolist.add(info.split(" ")[i]);
                                    }
                                }
                                MessageTranslatorUtil.saveVaisalaDatePWD(infolist, HspUtil.map, ip);
                                infolist = new ArrayList<>();
                            }
                        }
                    }
                }catch (Exception e){
                    e.printStackTrace();
                    System.out.println("会话中断！");
                    try {
                        socket.close();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }
            }else{//dtu走这
                try {
                    // 装饰流BufferedReader封装输入流（接收客户端的流）
                    BufferedInputStream bis = new BufferedInputStream(
                            socket.getInputStream());

                    DataInputStream dis = new DataInputStream(bis);
                    byte[] bytes = new byte[1024]; // 一次读取一个byte
                    String ret = "";

                    int recvMsgSize;

                    while ((recvMsgSize = dis.read(bytes)) != -1) {
                        ret = XwSocketUtil.toHexString(bytes);
                        ret = ret.substring(0, recvMsgSize * 2);
                        if (dis.available() == 0) { //一个请求
                            System.out.println("ret1--"+ret);
                            //如果是dtu设置返回数据
                            if(ret.startsWith("7573722E636E23") || ret.startsWith("7777772e7573722e636e23")){
                                String ret2 = XwSocketUtil.hexStringToString(ret);
                                HspUtil.dtuMap.put(sensorNo,ret2.trim());
                                System.out.println(ret2.trim());
                            }
                            //注册包
                            else if(ret.startsWith("AA")||ret.startsWith("AB")){
                                String no = ret;
                                //查找是否存在
                                if(HspUtil.map.containsKey(no)){
                                    Socket clientSocket = HspUtil.map.get(no).getSocket();
                                    if(clientSocket != null){
                                        try{
                                            if(!clientSocket.isClosed()){
                                                clientSocket.close();
                                                System.out.println("关闭原有"+ret+"链接！");
                                            }
                                        }catch(Exception e){

                                        }
                                    }
                                    //存放会话
                                    HspUtil.map.get(no).setSocket(socket);
                                    sensorNo = no;
//            					System.out.println(ret);
                                }
                                System.out.println(ret+"建立连接！");
                            }else if(ret.startsWith("BB")){//如果20分钟设备没上信息（通过查询设备状态确定）,关闭原来链接，放置新的链接
                                String no = "AA"+ret.substring(2);
                                if(HspUtil.map.containsKey(no)) {
                                    Map<String, LhpEquipmentEntity> LemMap = HspUtil.map.get(no).getEquipmentMap();
                                    if (LemMap != null) {
                                        for (Map.Entry<String, LhpEquipmentEntity> entry : LemMap.entrySet()) {//遍历所有设备，查询设备状态
                                            LhpEquipmentEntity le = entry.getValue();
                                            if (1==le.getEquipmentStatus()) {
                                                //存放会话
                                                HspUtil.map.get(no).setSocket(socket);
                                                sensorNo = no;
                                                System.out.println(ret+"重新放入连接！");
                                                break;
                                            }
                                        }
                                    }
                                }
                            }else if(ret.startsWith("0110")){//路赋德的二进制数据
                                try{
                                    // System.out.println("ret----"+ret);
                                    MessageTranslatorUtil.saveLUFFTBinaryValue(ret,HspUtil.map,sensorNo);
                                }catch(Exception e){
                                    //System.out.println(ret);
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                    socket.shutdownInput();//关闭输入流
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("会话中断！");
                    try {
                        socket.close();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }finally {

                }
            }
        }
    }
    /***************************数据报文接收结束******************************/



    /****************************发送报文开始********************************/
    private class pollThread implements Runnable {
        private DataCollection dataCollection;
        public pollThread(DataCollection dc){
            dataCollection = dc;
            Socket socket = dataCollection.getSocket();
            if(socket!=null && !socket.isClosed()) {
                new Thread(this).start();
            }
        }
        public void run() {

            Socket socket = dataCollection.getSocket();

            if(socket!=null && !socket.isClosed()){
                HashMap<String, LhpEquipmentEntity> equipmentMap=dataCollection.getEquipmentMap();
                for (Map.Entry<String,LhpEquipmentEntity> entryLem :equipmentMap .entrySet()){

                    try{
                        LhpEquipmentEntity lem = entryLem.getValue();
                        if(lem.getManufactorType()==0){ //如果是维萨拉设备
                            if(lem.getEquipmentType()==0){  //组合
                                for(int i=0;i<5;i++){
                                    sendData("4031204D4553203136200D0A",socket.getOutputStream());
                                    Thread.sleep(3500);
                                }
                            }else if(lem.getEquipmentType()==1){//能见度
                                sendData("0D055057203920300D",socket.getOutputStream());//指令
                            }
                        }else if(lem.getManufactorType()==1){//如果是路赋特设备
                            if(lem.getEquipmentType()==1){ //能见度
                                sendData(XwSocketUtil.creatLUFFTSendPacage("1", "3"), socket.getOutputStream());
                            }else if(lem.getEquipmentType()==2){//气象站
                                sendData(XwSocketUtil.creatLUFFTSendPacage("1", "7"), socket.getOutputStream());
                            }else if(lem.getEquipmentType()==3){//地面
                                sendData(XwSocketUtil.creatLUFFTSendPacage("1", "9"), socket.getOutputStream());
                            }
                        }
                        delay();
                    }catch(Exception e){
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    /****************************发送报文结束********************************/
}
